package com.bs.service;


import com.bs.domain.ServiceInfo;
import com.bs.utils.DataRow;
import com.bs.utils.DataRowCollection;
import com.bs.utils.DataTable;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.TermsBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author: rui xu
 * @Date: 2019/2/25 15:24
 */

@Service
public class SlowSvcService {

    @Autowired
    ElasticsearchTemplate elasticsearchTemplate;
    @Autowired
    ModuleNameService moduleNameService;
    private final Logger log = LoggerFactory.getLogger(ModuleNameService.class);
    private String partition;
    private String startTime;
    private String endTime;
    private String code;
    private long time;
    private List<Map<String, String>> lv0List;
    private List<Map<String, String>> lv1List;
    private List<Map<String, String>> lv2List;
    private List<ServiceInfo> svcList;
    private List<ServiceInfo> serviceInfoList;
    private DataRowCollection rows;

    /**
     * 查询慢svc
     *
     * @return
     */
    private SearchResponse getSlowSvcResponse() {
        String index = "";
        Client transportClient = elasticsearchTemplate.getClient();
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchPhrasePrefixQuery("logmsg", ". service end"));
        builder.must(QueryBuilders.rangeQuery("exec_time").gt(time));
        builder.filter(QueryBuilders.boolQuery()
            .must(QueryBuilders.rangeQuery("@timestamp").from(startTime).to(endTime).timeZone("+08:00"))
            .must(QueryBuilders.termQuery("partition", partition)));

        if (!code.equals("")) {
            index = "logstash-" + code + "-svcsql-*";
        }
        SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(index).setTypes("log");
//        TermsBuilder svcAgg = AggregationBuilders.terms("svc").field("svc").size(1000);
//        TermsBuilder timeAgg = AggregationBuilders.terms("logtime").field("logtime").size(1000);

        return searchRequestBuilder
            .setQuery(builder)
            .setSize(1000)
            .addSort("logtime", SortOrder.DESC)
            //    .addAggregation(svcAgg.subAggregation(timeAgg))
            .execute().actionGet();
    }

    /**
     * 获取所得慢服务
     *
     * @param partition
     * @param startTime
     * @param endTime
     * @param time
     * @param code
     * @return
     */
    public List<Map<String, String>> slowSvcResource(String partition, String startTime, String endTime, long time, String code) {

        this.partition = partition;
        this.startTime = startTime;
        this.endTime = endTime;
        this.code = code;
        this.time = time;
        serviceInfoList = new ArrayList<>();
        ServiceInfo slowServiceInfo = null;
        SearchResponse response = getSlowSvcResponse();
        SearchHit[] searchHits = response.getHits().getHits();
        for (SearchHit searchHits1 : searchHits) {
            String svc = (String) searchHits1.getSource().get("svc");
            int execTime = (int) searchHits1.getSource().get("exec_time");
            String logTime = (String) searchHits1.getSource().get("logtime");
            String partitionKey = (String) searchHits1.getSource().get("partition");
            slowServiceInfo = new ServiceInfo(svc, logTime, execTime, partitionKey);
            serviceInfoList.add(slowServiceInfo);
        }

        return treeMap(partition);

    }


    /**
     * 获取树集合
     *
     * @param partition
     */
    public List<Map<String, String>> treeMap(String partition) {
        String sql = " select sub_system_fname, sub_system_ename, '0' as lv from tea02 where sub_system_fname = 'root' " +
            "union all " +
            "select sub_system_fname, sub_system_ename, '1' as lv from tea02 where sub_system_fname <> 'root' " +
            "union all " +
            "select sub_system_ename, tea03.SVC_NAME, '2' from tea01, tea03 where tea03.FUNC_TYPE = 'S' and tea01.svc_name = tea03.svc_name";
        lv0List = new ArrayList<>();
        lv1List = new ArrayList<>();
        lv2List = new ArrayList<>();
        svcList = new ArrayList();
        DataTable table = moduleNameService.getModule(partition, sql, "");
        rows = table.getRows();
        for (DataRow dataRow : rows) {
            if (("0").equals(dataRow.getValue("LV").toString())) {
                Map<String, String> lv0Map = new HashMap<>();
                lv0Map.put("Name", dataRow.getValue("SUB_SYSTEM_FNAME").toString());
                lv0Map.put("SubNodes", dataRow.getValue("SUB_SYSTEM_ENAME").toString());
                lv0List.add(lv0Map);
            } else if (("1").equals(dataRow.getValue("LV").toString())) {
                Map<String, String> lv2Map = new HashMap<>();
                lv2Map.put("Name", dataRow.getValue("SUB_SYSTEM_FNAME").toString());
                lv2Map.put("SubNodes", dataRow.getValue("SUB_SYSTEM_ENAME").toString());
                lv1List.add(lv2Map);
            } else if (("2").equals(dataRow.getValue("LV").toString())) {
                Map<String, String> lv2Map = new HashMap<>();
                lv2Map.put("Name", dataRow.getValue("SUB_SYSTEM_FNAME").toString());
                lv2Map.put("SubNodes", dataRow.getValue("SUB_SYSTEM_ENAME").toString());
                lv2List.add(lv2Map);
            }
        }
        List<ServiceInfo> serviceInfos = MixedSvc();
        for (Map<String, String> dataRow : lv1List) {
            int count = 0;
            for (ServiceInfo si : serviceInfos) {
                if (si.getService().indexOf((dataRow.get("SubNodes").toString().toLowerCase())) != -1) {
                    count++;
                }
            }
            Map<String, String> lv1Map = new HashMap<>();
            lv1Map.put("Name", dataRow.get("Name").toString());
            lv1Map.put("SubNodes", dataRow.get("SubNodes").toString() + "【" + count + "】");
            lv0List.add(lv1Map);
        }
        return lv0List;
    }

    /**
     * 获取所有慢服务与SQL查询服务的交集
     *
     * @return
     */
    public List<ServiceInfo> MixedSvc() {
        svcList = new ArrayList();
        for (ServiceInfo si : serviceInfoList) {
            for (Map<String, String> row : lv2List) {
                if (si.getService().equals(row.get("SubNodes").toString())) {
                    svcList.add(si);
                }
            }
        }
        return svcList;
    }


    /**
     * 获取画面对应的svc
     *
     * @param svc
     * @return
     */

    public List<ServiceInfo> findSvc(String svc) {
        List<ServiceInfo> sInfoList = new ArrayList();
        for (ServiceInfo si : svcList) {
            if (si.getService().indexOf(svc.toLowerCase()) != -1) {
                sInfoList.add(si);
            }
        }


        return sInfoList;
    }


}
